home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / icmphdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  2.2 KB  |  104 lines

  1. /* ICMP header conversion routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "internet.h"
  7. #include "ip.h"
  8. #include "icmp.h"
  9.  
  10. /* Generate ICMP header in network byte order, link data, compute checksum */
  11. struct mbuf *
  12. htonicmp(icmp,data)
  13. struct icmp *icmp;
  14. struct mbuf *data;
  15. {
  16.     struct mbuf *bp;
  17.     char *cp;
  18.     int16 checksum;
  19.  
  20.     if((bp = pushdown(data,ICMPLEN)) == NULLBUF)
  21.         return NULLBUF;
  22.     cp = bp->data;
  23.  
  24.     *cp++ = icmp->type;
  25.     *cp++ = icmp->code;
  26.     cp = put16(cp,0);        /* Clear checksum */
  27.     switch(icmp->type){
  28.     case ICMP_DEST_UNREACH:
  29.         if(icmp->code == ICMP_FRAG_NEEDED){
  30.             /* Deering/Mogul max MTU indication */
  31.             cp = put16(cp,0);
  32.             cp = put16(cp,icmp->args.mtu);
  33.         } else
  34.             cp = put32(cp,0L);
  35.         break;
  36.     case ICMP_PARAM_PROB:
  37.         *cp++ = icmp->args.pointer;
  38.         *cp++ = 0;
  39.         cp = put16(cp,0);
  40.         break;
  41.     case ICMP_REDIRECT:
  42.         cp = put32(cp,icmp->args.address);
  43.         break;
  44.     case ICMP_ECHO:
  45.     case ICMP_ECHO_REPLY:
  46.     case ICMP_TIMESTAMP:
  47.     case ICMP_TIME_REPLY:
  48.     case ICMP_INFO_RQST:
  49.     case ICMP_INFO_REPLY:
  50.         cp = put16(cp,icmp->args.echo.id);
  51.         cp = put16(cp,icmp->args.echo.seq);
  52.         break;
  53.     default:
  54.         cp = put32(cp,0L);
  55.         break;
  56.     }
  57.     /* Compute checksum, and stash result */
  58.     checksum = cksum(NULLHEADER,bp,len_p(bp));
  59.     cp = &bp->data[2];
  60.     cp = put16(cp,checksum);
  61.  
  62.     return bp;
  63. }
  64.  
  65. /* Pull off ICMP header */
  66. int
  67. ntohicmp(icmp,bpp)
  68. struct icmp *icmp;
  69. struct mbuf **bpp;
  70. {
  71.     char icmpbuf[8];
  72.  
  73.     if(icmp == (struct icmp *)NULL)
  74.         return -1;
  75.     if(pullup(bpp,icmpbuf,8) != 8)
  76.         return -1;
  77.     icmp->type = icmpbuf[0];
  78.     icmp->code = icmpbuf[1];
  79.     switch(icmp->type){
  80.     case ICMP_DEST_UNREACH:
  81.         /* Retrieve Deering/Mogul MTU value */
  82.         if(icmp->code == ICMP_FRAG_NEEDED)
  83.             icmp->args.mtu = get16(&icmpbuf[6]);
  84.         break;
  85.     case ICMP_PARAM_PROB:
  86.         icmp->args.pointer = icmpbuf[4];
  87.         break;
  88.     case ICMP_REDIRECT:
  89.         icmp->args.address = get32(&icmpbuf[4]);
  90.         break;
  91.     case ICMP_ECHO:
  92.     case ICMP_ECHO_REPLY:
  93.     case ICMP_TIMESTAMP:
  94.     case ICMP_TIME_REPLY:
  95.     case ICMP_INFO_RQST:
  96.     case ICMP_INFO_REPLY:
  97.         icmp->args.echo.id = get16(&icmpbuf[4]);
  98.         icmp->args.echo.seq = get16(&icmpbuf[6]);
  99.         break;
  100.     }
  101.     return 0;
  102. }
  103.  
  104.